#include "serial_connect.h"

Serial_connect::Serial_connect(QObject *parent) : QObject(parent),
    m_modbus(new QModbusRtuSerialMaster(this))
{



}

bool Serial_connect::MB_connect()
{

    if (m_modbus->state() != QModbusDevice::ConnectedState) {
        m_modbus->setConnectionParameter(QModbusDevice::SerialPortNameParameter,
            m_MBSetting.port);
        m_modbus->setConnectionParameter(QModbusDevice::SerialParityParameter,
            m_MBSetting.parity);
        m_modbus->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,
            m_MBSetting.baud);
        m_modbus->setConnectionParameter(QModbusDevice::SerialDataBitsParameter,
            m_MBSetting.dataBits);
        m_modbus->setConnectionParameter(QModbusDevice::SerialStopBitsParameter,
           m_MBSetting.stopBits);

    }
    m_modbus->setTimeout(m_MBSetting.responseTime);
    m_modbus->setNumberOfRetries(m_MBSetting.numberOfRetries);
        if (!m_modbus->connectDevice()) {

            qDebug()<<"error connect";
//            emit connectstate(false);
            return false;

        } else {
            qDebug()<<"connecting";
            //DataQueue news={0,0};
            //m_Serqueue.enqueue(news);//添加初始队列
//            emit connectstate(true);
            return true;

        }

}

void Serial_connect::MB_disconnect()
{
    m_modbus->disconnectDevice();

}

void Serial_connect::set_port_settings(ModBSettings m_port_set)
{
    m_MBSetting=m_port_set;
    m_MBSetting.infoshow();

}

void Serial_connect::Deal_signal(Modbus_flag flag, QVector<QString> vec, bool is_small_one)
{
    if (m_modbus->state() != QModbusDevice::ConnectedState)
    {
        sendError("NO Connecting!");
        return;
    }
    else
    {
        //for other prepare code
        qDebug()<<"Deal serial!";

        switch(flag)
        {
            case Modbus_flag::Init:
        {
            if(is_small_one)
            {
                setStage_count(1);
                QModbusDataUnit initial_data(QModbusDataUnit::HoldingRegisters,4,7);
                QModbusDataUnit distance(QModbusDataUnit::HoldingRegisters,9,2);
//                flight_lead:
                initial_data.setValue(0,static_cast<quint16>(360));
                initial_data.setValue(1,static_cast<quint16>(0));
//                mechinical Zero point(enable):
                initial_data.setValue(2,static_cast<quint16>(1));
//                stop mode(0:slow,1:quick):
                initial_data.setValue(3,static_cast<quint16>(0));
//                set_speed(rpm not exceed 200):
                initial_data.setValue(4,static_cast<quint16>(100));
//                distance to go: per round to 4.55degree:
                initial_data.setValue(5,static_cast<quint16>(0));
                initial_data.setValue(6,static_cast<quint16>(0));

                distance.setValue(0,static_cast<quint16>(0));
                distance.setValue(1,static_cast<quint16>(0));

                int motor_address=1;

                if(stage_count==1)
                {
                    motor_address+=1;
                }


                 if (auto *reply = m_modbus->sendWriteRequest(initial_data, motor_address)) {

                     if (!reply->isFinished()) {
                         connect(reply, &QModbusReply::finished,this,&Serial_connect::writefinishReady);

                     } else {
                         // broadcast replies return immediately
                         reply->deleteLater();
                     }
                 } else {
                    emit sendError(tr("Write Initial error: ") + m_modbus->errorString());

                 }

            }
            else
            {}

        }
                break;
            case Modbus_flag::Angle:
                if(is_small_one)
                {}
                else
                {}
                break;
            case Modbus_flag::Speed:
                if(is_small_one)
                {}
                else
                {}
                break;
            case Modbus_flag::Run:
                if(is_small_one)
                {}
                else
                {}
                break;
            case Modbus_flag::Stop:
                if(is_small_one)
                {}
                else
                {}
                break;
            case Modbus_flag::Zero:
                if(is_small_one)
                {}
                else
                {}
                break;
            default:
                break;

        }
    }

}

void Serial_connect::readReady()
{

}

void Serial_connect::writefinishReady()
{
    auto reply = qobject_cast<QModbusReply *>(sender());
    if (!reply)
        return;
    if (reply->error() == QModbusDevice::ProtocolError) {
        qDebug()<<"Werror1";
       emit sendError(tr("Write response error: %1 (Mobus exception: 0x%2)")
            .arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16));

        return;
    } else if (reply->error() != QModbusDevice::NoError) {
        qDebug()<<"Werror2";
        emit sendError(tr("Write response error: %1 (code: 0x%2)").
            arg(reply->errorString()).arg(reply->error(), -1, 16));

        return;

    }

    reply->deleteLater();
//    for another start commander
    if(getStage_count()>0)
    {
        short temp=getStage_count();
        setStage_count(temp-1);
        //to startnextcode
        QVector<QString> prepare_data;

        switch(m_current_state){
        case Modbus_flag::Init:{
            if(is_smallTable)
            {
                emit startInfo(m_current_state,prepare_data,is_smallTable);
            }
            else
            {

            }
            break;

        }
        case Modbus_flag::Angle:{

            break;

        }
        case Modbus_flag::Speed:{

            break;

        }
        case Modbus_flag::Run:{

            break;

        }
        case Modbus_flag::Stop:{

            break;

        }
        }
    }
    else
    {
        setCurrent_state(Modbus_flag::Draft);
    }

}

bool Serial_connect::getIs_smallTable() const
{
    return is_smallTable;
}

void Serial_connect::setIs_smallTable(bool value)
{
    is_smallTable = value;
}

Modbus_flag Serial_connect::getCurrent_state() const
{
    return m_current_state;
}

void Serial_connect::setCurrent_state(const Modbus_flag &current_state)
{
    m_current_state = current_state;
}

short Serial_connect::getStage_count() const
{
    return stage_count;
}

void Serial_connect::setStage_count(short value)
{
    stage_count = value;
}

void ModBSettings::infoshow()
{
    qDebug()<<this->baud;
    qDebug()<<this->port;
    qDebug()<<this->parity;
    qDebug()<<this->dataBits;
    qDebug()<<this->stopBits;
    qDebug()<<this->responseTime;
    qDebug()<<this->numberOfRetries;
}
